package com.scalar.chiptrack.jobs.systemjobs;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.jobs.ReportConfiguration;
import com.scalar.chiptrack.jobs.Job;
import com.scalar.chiptrack.jobs.dao.JobDAO;
import com.scalar.chiptrack.utils.ConfigManager;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.ReflectionUtils;
import com.scalar.chiptrack.utils.ClassUtils;
import com.scalar.chiptrack.utils.DateUtil;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.utils.Mailer;
import com.scalar.chiptrack.operations.release.ReleaseHelper;
import com.scalar.ScalarException;
import com.enterprisedt.net.ftp.FTPException;
import com.enterprisedt.net.ftp.FTPClient;

import java.lang.reflect.Method;
import java.io.File;
import java.io.FileWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.util.Date;

import org.apache.poi.ss.usermodel.Workbook;

/**
 * User: Sujan Kumar Suppala
 * Date: Feb 19, 2009
 * Time: 10:58:42 AM
 */
public class ReportMailingJob extends JobHandler
{
   private Logger m_Logger    = null;

    public ReportMailingJob() throws ScalarException
    {
        /*try
        {
            m_Logger = new Logger(  "/logs", "ReportMailingJob", "Parser", "debug", 1024 * 1000, 1 ); //new Logger( ConfigManager.getLogDirectory(), "ReportMailingJob", "", "debug", 1024 * 1000, 1 );
        }
        catch (ScalarException se)
        {
            //log("ERROR!! ERROR!! ERROR!! Exception while creating Logger, Exception: " + se );
            throw se;
        }*/
    }

    public void execute() throws Exception
    {
        printVersionInfo();
        String subject;
        String message = "";
        String[] mailAttachments = null;
        String[] emailArray = JobDAO.getJobAlertUserEmails( null, getJob().getId() );
        String from = ConfigManager.getScalarAdminEmail();
        String toEmailIds = StringUtils.concatStrings( emailArray, Mailer.EMAIL_SEPARATOR );
        toEmailIds = StringUtils.removeDuplicateEmailIds(toEmailIds);

        if ( StringUtils.isNullOrEmpty( toEmailIds )  && getJob().getFtpUrl() == null )
        {
            throw new ScalarException ( "No users found to send report email" );
        }
        ReportConfiguration reportConfiguration = JobDAO.getReortConfiguration( null, getName() );
        if ( reportConfiguration == null )
        {
            throw new ScalarException ( "Report Configuration not found for the report name: " + getName() );
        }
        
        Class clazz = ClassUtils.forName( reportConfiguration.getReportClassName() );
        Method method = ReflectionUtils.findMethod( clazz, reportConfiguration.getReportMethodName(), reportConfiguration.getParamTypes() );
        log ( "Invoking report method:" + reportConfiguration.getReportClassName()+"."+reportConfiguration.getReportMethodName() );
        Object reportReturned = ReflectionUtils.invokeMethod( method, null, reportConfiguration.getFilledArgs(toEmailIds) );

        String attachmentFilePath = null;
        if ( reportReturned != null )
        {
            if ( "FILE_PATH".equalsIgnoreCase( reportConfiguration.getReportMethodReturnType() ) ) //returns the report file path(for pdf)
            {
                attachmentFilePath = (String)reportReturned;
            }
            else
            {
                String fileNameWithoutExtn = null;
                String fileExtn = null;
                String fileTimestampFormat = null;
                String attachmentFileName = null;
                try
                {
                    if ( reportConfiguration.getReportFileNameWithExtn().lastIndexOf('.') > 0 )
                    {
                        fileNameWithoutExtn = reportConfiguration.getReportFileNameWithExtn().substring( 0, reportConfiguration.getReportFileNameWithExtn().lastIndexOf('.') );
                        fileExtn = reportConfiguration.getReportFileNameWithExtn().substring( reportConfiguration.getReportFileNameWithExtn().lastIndexOf('.')+1 );
                    }
                    else
                    {
                        fileNameWithoutExtn = reportConfiguration.getReportFileNameWithExtn();
                    }

                    if ("BLANK".equalsIgnoreCase( reportConfiguration.getFilenameTimestampFormat() ) )
                    {
                         attachmentFileName = fileNameWithoutExtn + (fileExtn != null ? "."+fileExtn : "" );
                    }
                    else
                    {
                        fileTimestampFormat = StringUtils.formatDateToString(new Date(), reportConfiguration.getFilenameTimestampFormat() == null ? DateUtil.getTimeStamp() : reportConfiguration.getFilenameTimestampFormat() );
                        attachmentFileName = fileNameWithoutExtn + "_" + fileTimestampFormat + (fileExtn != null ? "."+fileExtn : "" );
                    }   

                    String mailingTempDir = ConfigManager.getMailerTempDir();
                    File tempDir = new File (mailingTempDir).getCanonicalFile();
                    tempDir.mkdirs();
                    File attachmentFile = new File( tempDir.getCanonicalPath(), attachmentFileName );
                    attachmentFile.deleteOnExit();
                    if ( "CONTENT_STRING".equalsIgnoreCase( reportConfiguration.getReportMethodReturnType() ) ) //returns the report content as String(for csv, txt)
                    {
                        if( attachmentFile.exists() || attachmentFile.createNewFile() )
                        {
                            FileWriter fWriter = new FileWriter(attachmentFile, false);

                            fWriter.write( (String)reportReturned );
                            if ( fWriter != null )
                            {
                                try
                                {
                                    fWriter.flush();
                                } catch ( IOException ignore ) {}
                                try
                                {
                                    fWriter.close();
                                }catch ( IOException ignor ) {}
                            }
                        }
                    }
                    else if ( "WORK_BOOK".equalsIgnoreCase( reportConfiguration.getReportMethodReturnType() ) ) //returns workbook object(for xls)
                    {
                        if( attachmentFile.exists() || attachmentFile.createNewFile() )
                        {
                            FileOutputStream fileOut = new FileOutputStream( attachmentFile, false  );
                            Workbook workbook = (Workbook)reportReturned;
                            if ( workbook != null )
                            {
                                workbook.write( fileOut );
                            }
                            fileOut.close();
                            fileOut = null;
                        }

                    }
                    else
                    {
                        throw new ScalarException ( "Could not understand Report Method Returned Object, configured return type is: " + reportConfiguration.getReportMethodReturnType() );
                    }
                    //If We want to Upload to FTP
                    if (getJob().getFtpUrl() != null && getJob().getFtpUrl().trim().length() > 0 )
                    {
                       uploadToFTPDirectory( attachmentFile.getCanonicalPath(), getJob() );
                       log ( "Report uploaded to FTP successfully" );
                    }
                    attachmentFilePath = attachmentFile.getAbsolutePath();
                }
                catch (Exception e )
                {
                    e.printStackTrace();
                }
            }
            mailAttachments = new String[]{attachmentFilePath};
        }
        else
        {
            if ( "HTML_EMAIL".equalsIgnoreCase( reportConfiguration.getReportMethodReturnType() ) ) // for Notification alert email
            {
                return;
            }
            log ( "Report method returned NULL object" );
            message += "<br>NULL report found.";
        }
        log ( "Sending report mail....");
        subject = reportConfiguration.getSubject();
        message = message + "<br>";
        if ( !StringUtils.isNullOrEmpty( toEmailIds ) )
        {
            Mailer.send( from, toEmailIds, null, null, subject, message, mailAttachments, Mailer.CONTENT_TYPE_HTML, false );
            log ( "Report mail sent successfully" );
        }
    }
    private void log(String message)
    {
        if (message == null) return;

        if (m_Logger != null)
        {
            synchronized (m_Logger)
            {
                m_Logger.logDebug(message + LINE_SEPARATOR);
            }
        }
        else
        {
            System.out.println(message);
        }
    }
    public static void uploadToFTPDirectory( String fileName, Job job ) throws Exception
    {
        try
        {
            FTPClient ftpClient = ReleaseHelper.login( job.getFtpUrl(), 21, job.getUserName(), job.getPassword(), job.getConnectionMode() );

            try
            {
                ftpClient.chdir( job.getDirectory() );  //try to cghange the directory
            }
            catch( FTPException ftpe)
            {
                ftpClient.mkdir( job.getDirectory() );
                ftpClient.chdir( job.getDirectory() );
            }

            ftpClient.put( new FileInputStream( fileName ), new File( fileName ).getName() );
            try
            {
                ReleaseHelper.logout( ftpClient );
            }catch ( Exception ignore ){ }
        }
        catch(Exception e)
        {
            e.printStackTrace();
            throw new ScalarException( "Exception uploading File"+fileName, e.getCause());
        }
    }
    private void printVersionInfo()
    {
        String info = "\n\n+----------- Running Report Job on " + new java.util.Date(System.currentTimeMillis()) + " -------------+\n" +
               "\n+---------------------------------------------------------------+\n" +
               "+                                                                \n" +
               "+              "+ getName() +  " Report Job - Beta            \n" +
               "+                                                                \n" +
               "+    Copy Right (C) 2009 - ScalarSoft Inc., All rights reserved.  \n" +
               "+                                                                \n" +
               "+---------------------------------------------------------------+\n";
        log(info);
    } //end of printVersionInfo

    public static void main( String agrs[] ) throws Exception
    {
		ReportMailingJob reportMailingJob = new ReportMailingJob();
        reportMailingJob.setName( "PERFORMANCE REPORT");
        reportMailingJob.execute();
	}
}
